//	--------------------------------------------------------------------
//	Copyright(C) 2006,2007 Zhao Yukun. All rights reserved.
//	This file is a part of the Xeres system.
//	Xeres 2007
//	Contact : xeres.engine@gmail.com
//	$(reservedInfo)
//	$(reservedDeclaration)
//	--------------------------------------------------------------------
///	@file	<CRenderState10.cpp>
///	@path	~/src/graphics/dx10/
///	@date	2008/12/22
///	@desc	.

#include "config/config.h"

#include "graphics/DxHelpers.h"
#include "graphics/dx10/import_dx10.h"
#include "graphics/dx10/CRenderState10.h"

namespace xeres {
	
	IMPL_IOBJECT_CLASS( CRenderState10 );

	// CRenderState10
	CRenderState10::CRenderState10( ID3D10StateBlock * block , D3D10_STATE_BLOCK_MASK * mask )
		: m_state( block )
		, m_lost( true )
	{
		memcpy( &m_mask , mask , sizeof(D3D10_STATE_BLOCK_MASK) );
	}
	// CRenderState10
	CRenderState10::~CRenderState10( void )
	{
		if( m_state )
		{
			UINT rest = m_state->Release();
			if( rest != 0 )
			{
				TRACE_ERROR( _S("CRenderState10::DTOR: Invalid IDirect3DStateBlock9 reference count.") );
				FATAL_ABORT( _S("Invalid ID3D10StateBlock reference count.") );
			}
		}
	}
	// Capture
	bool CRenderState10::Capture( void )
	{
		HRESULT hr = m_state->Capture();
		if( FAILED(hr) )
		{
			TRACE_ERROR( _S("CRenderState10::Capture: Failed to capture state: %s.") , d3d_get_err(hr) );
			return false;
		}
		m_lost = false;
		return true;
	}
	// Apply
	bool CRenderState10::Apply( void )
	{
		XS_ASSERT( !m_lost );

		HRESULT hr = m_state->Apply();
		if( FAILED(hr) )
		{
			TRACE_ERROR( _S("CRenderState10::Apply: Failed to apply state: %s.") , d3d_get_err(hr) );
			return false;
		}
		return true;
	}
	// RequireCapture
	bool CRenderState10::RequireCapture( void )
	{
		return m_lost;
	}
	// OnLostDevice
	bool CRenderState10::OnLostDevice( void )
	{
		if( m_state )
		{
			UINT rest = m_state->Release();
			if( rest != 0 )
			{
				TRACE_ERROR( _S("CRenderState10::OnLostDevice: Invalid IDirect3DStateBlock9 reference count.") );
				FATAL_ABORT( _S("Invalid IDirect3DStateBlock9 reference count.") );
			}
		}
		m_state = NULL;
		m_lost = true;
		return true;
	}
	// OnResetDevice
	bool CRenderState10::OnResetDevice( RefWeak<IDevice> device )
	{
		RefWeak<CDevice10> d3d10( device );
		HRESULT hr = dx10::D3D10CreateStateBlock( d3d10->GetDevice() , &m_mask , &m_state );
		if( FAILED(hr) )
		{
			TRACE_ERROR( _S("CRenderState10::OnResetDevice: Failed to create render state: %s") , d3d_get_err(hr) );
			return false;
		}
		m_lost = true;
		return true;
	}
} // namespace xeres
